﻿using XmlStudio.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using XmlStudio.Interfaces;
using XmlStudio.DataLayer;
using System.Collections.Generic;
using XmlStudio.Enums;
using XmlStudio.Models;
using XmlStudio.Controllers.Interfaces;

namespace XmlStudio.Tests {
    /// <summary>
    ///This is a test class for XmlControllerTest and is intended
    ///to contain all XmlControllerTest Unit Tests
    ///</summary>
    [TestClass()]
    public class XmlControllerTest {
        #region Fields
        private TestContext testContextInstance;
        IXmlModel model;
        IController controller;
        #endregion

        #region Properties
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext {
            get {
                return testContextInstance;
            }
            set {
                testContextInstance = value;
            }
        }
        #endregion

        [TestInitialize]
        public void MyTestInitialize() {
            this.model = ModelFactory.CreateXmlModel();
            this.controller = ControllerFactory.CreateController(model, null);
            this.controller.OpenXmlFile(Common.PathShiporder);
        }

        /// <summary>
        /// A test for ValidateXsdAsync. Test for method existence.
        ///</summary>
        [TestMethod]
        public void ValidateXsdAsyncTest() {
            this.controller.ValidateXsdAsync();
        }

        /// <summary>
        /// A test for ValidateDtdAsync. Test for method existence.
        ///</summary>
        [TestMethod]
        public void ValidateDtdAsyncTest() {
            controller.OpenXmlFile(Common.PathTsmt);
            controller.ValidateDtdAsync();
        }

        /// <summary>
        /// A test for ValidateDtd. Test for method existence.
        ///</summary>
        [TestMethod]
        public void ValidateDtdTest() {
            this.controller.ValidateDtd();
        }

        /// <summary>
        /// A test for UpdateAttributes. Test for method existence.
        ///</summary>
        [TestMethod]
        public void UpdateAttributesTest() {
            var node = this.controller.GetRootElement();
            IDictionary<string, IBigXmlAttribute> attributes = new Dictionary<string, IBigXmlAttribute>();
            this.controller.UpdateAttributes(node, attributes);
        }

        /// <summary>
        /// A test for Undo. Test for method existence.
        ///</summary>
        [TestMethod]
        public void UndoTest() {
            this.controller.Undo();
        }

        /// <summary>
        /// A test for SetView. Test for method existence.
        ///</summary>
        [TestMethod]
        public void SetViewTest() {
            this.controller.SetView(null);
        }

        /// <summary>
        /// A test for SetModel. Test for method existence.
        ///</summary>
        [TestMethod]
        public void SetModelTest() {
            this.controller.SetModel(ModelFactory.CreateXmlModel(Common.PathTest1));
        }

        /// <summary>
        /// A test for SetDocumentType. Test for method existence.
        ///</summary>
        [TestMethod]
        public void SetDocumentTypeTest() {
            string rootElementName = "shiporder";
            string publicId = string.Empty;
            string systemId = string.Empty;
            string internalSubset = string.Empty;
            this.controller.SetDocumentType(rootElementName, publicId, systemId, internalSubset);
        }

        /// <summary>
        /// A test for SelectNodes. Test for method existence.
        ///</summary>
        [TestMethod]
        public void SelectNodesTest() {
            string xpath = "test";
            this.controller.SelectNodes(xpath);
        }

        /// <summary>
        /// A test for Save. Test for method existence.
        ///</summary>
        [TestMethod]
        public void SaveTest() {
            this.controller.Save("XmlControllerSaveTest.xml");
        }

        /// <summary>
        /// A test for RenameElement. Test for method existence.
        ///</summary>
        [TestMethod]
        public void RenameElementTest() {
            var node = this.controller.GetRootElement();
            string name = "test";
            this.controller.RenameElement(node, name);
        }

        /// <summary>
        /// A test for RenameElement. Test for method existence.
        ///</summary>
        [TestMethod]
        public void RenameElementTest1() {
            var node = this.controller.GetRootElement();
            string localName = "test";
            string namespaceUri = string.Empty;
            string prefix = string.Empty;
            this.controller.RenameElement(node, localName, namespaceUri, prefix);
        }

        /// <summary>
        /// A test for RemoveNode. Test for method existence.
        ///</summary>
        [TestMethod]
        public void RemoveNodeTest() {
            var nodeToRemove = this.controller.GetRootElement();
            bool removeSubtree = true;
            this.controller.RemoveNode(nodeToRemove, removeSubtree);
        }

        /// <summary>
        /// A test for RemoveAttribute. Test for method existence.
        ///</summary>
        [TestMethod]
        public void RemoveAttributeTest() {
            var root = this.controller.GetRootElement();
            this.controller.AddAttribute(root, "test", "value");
            this.controller.RemoveAttribute(root, "test");
        }

        /// <summary>
        /// A test for RemoveAttribute. Test for method existence.
        ///</summary>
        [TestMethod]
        public void RemoveAttributeTest1() {
            var root = this.controller.GetRootElement();
            this.controller.AddAttribute(root, "p", "test", "http://www.xmlstudio.cz/", "value");
            this.controller.RemoveAttribute(root, "p", "test", "http://www.xmlstudio.cz/");
        }

        /// <summary>
        /// A test for Redo. Test for method existence.
        ///</summary>
        [TestMethod]
        public void RedoTest() {
            this.controller.Redo();
        }

        /// <summary>
        /// A test for OpenXmlFile. Test for method existence.
        ///</summary>
        [TestMethod()]
        public void OpenFileTest() {
            this.controller.OpenXmlFile(Common.PathBible1);
        }

        /// <summary>
        /// A test for MoveSubtree. Test for method existence.
        ///</summary>
        [TestMethod]
        public void MoveSubtreeTest() {
            var root = this.controller.GetRootElement();
            this.controller.ExpandNode(root);
            var child1 = root.ChildNodes[0];
            var child2 = root.ChildNodes[1];

            this.controller.MoveSubtree(child1, root, InsertMode.Last, null);
        }

        /// <summary>
        /// A test for ModifyTextNode. Test for method existence.
        ///</summary>
        [TestMethod]
        public void ModifyTextNodeTest() {
            this.controller.ExpandAll();
            var textNodes = this.controller.SelectNodes("//text()");
            Assert.IsTrue(textNodes.Count() > 0);
            this.controller.ModifyTextNode(textNodes.First(), "text");
        }

        /// <summary>
        /// A test for GetRootElement. Test for method existence.
        ///</summary>
        [TestMethod]
        public void GetRootElementTest() {
            var root = this.controller.GetRootElement();
            Assert.IsNotNull(root);
        }

        /// <summary>
        /// A test for GetRawXml. Test for method existence.
        ///</summary>
        [TestMethod]
        public void GetRawXmlTest() {
            var root = this.controller.GetRootElement();
            var rawXml = this.controller.GetRawXml();
            Assert.IsNotNull(rawXml);
        }

        /// <summary>
        /// A test for ExpandNode. Test for method existence.
        ///</summary>
        [TestMethod()]
        public void ExpandNodeTest() {
            var root = this.controller.GetRootElement();
            this.controller.ExpandNode(root);
        }

        /// <summary>
        /// A test for ExpandAll. Test for method existence.
        ///</summary>
        [TestMethod()]
        public void ExpandAllTest() {
            this.controller.ExpandAll();
        }

        /// <summary>
        /// A test for CreateTextNode. Test for method existence.
        ///</summary>
        [TestMethod]
        public void CreateTextNodeTest() {
            var node = this.controller.CreateTextNode("text");
            Assert.IsNotNull(node);
        }

        /// <summary>
        /// A test for CreateRootElement. Test for method existence.
        ///</summary>
        [TestMethod]
        public void CreateRootElementTest() {
            this.controller.RemoveNode(this.controller.GetRootElement(), true);
            this.controller.CreateRootElement("root");
        }

        /// <summary>
        /// A test for CreateRootElement. Test for method existence.
        ///</summary>
        [TestMethod]
        public void CreateRootElementTest1() {
            this.controller.RemoveNode(this.controller.GetRootElement(), true);
            this.controller.CreateRootElement("p", "root", "http://www.xmlstudio.cz/");
        }

        /// <summary>
        /// A test for CreateElement. Test for method existence.
        ///</summary>
        [TestMethod]
        public void CreateElementTest() {
            var element = this.controller.CreateElement("name");
            Assert.IsNotNull(element);
        }

        /// <summary>
        /// A test for CreateElement. Test for method existence.
        ///</summary>
        [TestMethod]
        public void CreateElementTest1() {
            var element = this.controller.CreateElement("p", "name", "http://www.xmlstudio.cz/");
            Assert.IsNotNull(element);
        }

        /// <summary>
        /// A test for AddAttribute. Test for method existence.
        ///</summary>
        [TestMethod]
        public void AddAttributeTest() {
            this.controller.AddAttribute(this.controller.GetRootElement(), "att", "val");
        }

        /// <summary>
        /// A test for AddAttribute. Test for method existence.
        ///</summary>
        [TestMethod]
        public void AddAttributeTest1() {
            this.controller.AddAttribute(this.controller.GetRootElement(), "p", "att", "http://www.xmlstudio.cz/", "val");
        }

        /// <summary>
        /// A test for AddChildElement. Test for method existence.
        ///</summary>
        [TestMethod]
        public void AddChildElementTest() {
            var root = this.controller.GetRootElement();
            this.controller.ExpandNode(root);
            this.controller.AddChildElement(root, "", "", "name", new Dictionary<string, IBigXmlAttribute>(), InsertMode.Last, null);
        }

        /// <summary>
        /// A test for AddChildTextNode. Test for method existence.
        ///</summary>
        [TestMethod]
        public void AddChildTextNodeTest() {
            var root = this.controller.GetRootElement();
            this.controller.ExpandNode(root);
            this.controller.AddChildTextNode(root, "text", InsertMode.Last, null);
        }

        /// <summary>
        /// A test for CancelValidateDtd. Test for method existence.
        ///</summary>
        [TestMethod]
        public void CancelValidateDtdTest() {
            this.controller.ValidateDtdAsync();
            this.controller.CancelValidateDtd();
        }

        /// <summary>
        /// A test for CancelValidateXsd. Test for method existence.
        ///</summary>
        [TestMethod]
        public void CancelValidateXsdTest() {
            this.controller.ValidateXsdAsync();
            this.controller.CancelValidateXsd();
        }

        /// <summary>
        /// A test for ChangeNodeOrder. Test for method existence.
        ///</summary>
        [TestMethod]
        public void ChangeNodeOrderTest() {
            var root = this.controller.GetRootElement();
            this.controller.ExpandNode(root);
            var child1 = root.ChildNodes[0];
            var child2 = root.ChildNodes[1];

            this.controller.ChangeNodeOrder(child1, child2);
        }

        /// <summary>
        /// A test for CollapseNode. Test for method existence.
        ///</summary>
        [TestMethod]
        public void CollapseNodeTest() {
            this.controller.ExpandAll();
            var root = this.controller.GetRootElement();
            this.controller.CollapseNode(root);
        }

        /// <summary>
        /// A test for CopySubtree. Test for method existence.
        ///</summary>
        [TestMethod]
        public void CopySubtreeTest() {
            var root = this.controller.GetRootElement();
            this.controller.ExpandNode(root);
            var child1 = root.ChildNodes[0];
            var child2 = root.ChildNodes[1];

            this.controller.CopySubtree(child1, root, InsertMode.Last, null);
        }
    }
}